import { camelize, CSSProperties, Directive, reactive } from "vue"
import { BaseValue, itemPreCls, ItemProps, Props } from "./interface"
import resizeobserver from "../_util/Dom/resizeobserver"
import { skeletonList } from "./skeleton"

const SkeletonItem: Directive<any, BaseValue> = {
  mounted(el, binding) {
    // @ts-ignore
    const props: Props = skeletonList.findLast(e => e.el.contains(el))
    if (!props) return
    const child = createItem(props, el, binding)
    props.targets.push(child)
  },
  beforeUnmount(el) {
    // @ts-ignore
    const props: Props = skeletonList.findLast(e => e.el.contains(el))
    if (!props) return
    const i = props.targets.findIndex(e => e.el === el)
    if (i < 0) return
    const child = props.targets[i]
    props.targets.splice(i, 1)
    resizeobserver.dispose(props.el, child.resizeCb)
  }
}

export default SkeletonItem

const createItem = (props: Props, el: ItemProps['el'], binding: ItemProps['binding']) => {
  el.classList.add(`${itemPreCls}-ref`)

  const { el: parentEl } = props

  const child: ItemProps = {
    el,
    binding,
    state: reactive({}),
    resizeCb: () => {
      const parentRect = parentEl.getBoundingClientRect(), parentStyle = getComputedStyle(parentEl)
      const style = getComputedStyle(el), rect = el.getBoundingClientRect()
      const _style: CSSProperties = { position: 'absolute' };
      // 对其位置
      ['top', 'left'].forEach(e => {
        const borderWidth = parseInt(parentStyle[camelize(`border-${e}-width`)])
        _style[e] = Math.abs(rect[e] - parentRect[e]) - borderWidth + 'px'
      });
      ['width', 'height'].forEach(e => _style[e] = Math.ceil(rect[e]) + 'px')
      _style.borderRadius = style.borderRadius
      _style.zIndex = +style.zIndex + 1
      child.state.style = _style
    }
  }

  child.resizeCb()
  
  resizeobserver.observer(parentEl, child.resizeCb)

  return child
}